
// task object prototype
function task(obj) {

	this.id = 'task123'; // = 'task' + (++_maxid) + '_' + smallrandom
	this.title = '';
	this.priority = 4; // default
	this.dueDate = new Date();
	this.location = '';
	this.tags = [];
	this.link = '';
	this.progress = 0; // = -1 to represent deleted task // TODO: isDeleted field?
	this.status = '';

	this.creator = '';
	this.owner = '';
	this.lastModifier = '';
	this.lastModified = null;

	this.completedDate = null; // if null - not completed
	this.completer = '';
	
	this.addedDate = null;
	this.freq = ''; // = 'after 1 day', 'daily', ...
	this.dur = '';

	this.isDeleted = function() {
		return this.progress == -1;
	};

	this.isCompleted = function() {
		return this.completedDate != null;
	};
	
	this.isToday = function() {
		return this.dueDate && this.dueDate.is().today();
	};
	
	this.isOverdue = function(){
		// not completed and late? (not including Today)
		return (!this.isCompleted() && this.dueDate != null && !this.isToday() 
			&& this.dueDate.getTime() < (new Date()).getTime()); 
	};
	
	// tests if a discussion wave for this task exists
	this.isLinkedToWave = function() {
		var twave = all_tasks_waves['w'+this.id];
		if (twave != "none" && twave != "create" && twave != undefined) {
			return true;
		}
		return false;
	};

	// returns link to discussion wave
	this.getLinkedWaveHref = function() {
		var twave = all_tasks_waves['w'+this.id];
		if (twave != "none" && twave != "create" && twave != undefined) {
		 
			// TODO: wave annoyances, any less stupid way to generate proper links to waves?
			
			// if on the Wave Preview site:
			var gwidindex = twave.indexOf('googlewave');
			
			if (gwidindex > 0)  {
				var waveid = twave.substring(gwidindex);
				twave = 'https://wave.google.com/wave/#restored:wave:' + waveid; 
			}

			twave = twave.replace('+','%252B'); 
			
			return twave;
		}
		return false;
	};

	// requests creation of a discussion wave
	this.createLinkedWave = function() {
		var twave = all_tasks_waves['w'+this.id];
		if (twave == null || twave == "none" || twave == undefined) {
		
		//	alert("[twave="+twave+"]");
		// request the robot to create a discussion wave
			setVal('w'+this.id, "create");
			
		}
	};
}


// a 'new' statement so Eclipse will recognize task() as a 'class', 
// and you could use auto-completion on its instances
var dummyTask = new task();

/*
 * A collection of all the tasks available (completed too) 
 */
var all_tasks = []; // indexed array
var all_tasks_vers = []; // assoc array of known <'v'+task.id, taskver> (no .length)
var all_tasks_waves = []; // assoc array of known <'w'+task.id, waveid> (no .length)

/*
 * Add task to state object.
 * Serialized via JSON.stringify().
 * task.id = uid = 'task' + (++_maxid) + '_' + smallrandom
 */
function addTask(task) {
	task.creator = wave.getViewer().getId();
	task.addedDate = new Date();
	task.lastModified = task.addedDate; // TODO: adding isn't a modification?
	task.lastModifier = wave.getViewer().getId();
	var state = wave.getState();
	var id = parseInt(state.get('_maxid','0')) + 1;
	var uid = 'task'+id+'_'+randStr(4);
	task.id = uid;
	var delta = {};
	delta[uid] = JSON.stringify(task);
	delta['v'+uid] = 1; // version of this task, init 1
	delta['w'+uid] = "none"; // task's discussion wave id
	delta['_maxid'] = id;
	state.submitDelta(delta);

	// gui will react to state changed callback
}

function updateTask(task) { // update single task in wave state
	var delta = {};
	var state = wave.getState();
	var uid = task.id;
	var tver = parseInt(state.get('v'+uid,'0')) + 1;
	if (tver <= 1) return; // not a real task
	task.lastModifier = wave.getViewer().getId();
	task.lastModified = new Date();
	delta[uid] = JSON.stringify(task);
	delta['v'+uid] = tver;
	state.submitDelta(delta);
}

function updateTasks(taskArr, fun) { // update tasks using fun(task) on each
	// notice - you get an array of tasks!
	var delta = {};
	var state = wave.getState();
	
	for (var i in taskArr) {
		var t = cloneTask(taskArr[i]);
		var uid = t.id;
		fun(t);
		t.lastModifier = wave.getViewer().getId();
		t.lastModified = new Date();
		var tver = parseInt(state.get('v'+uid,'0')) + 1;
		if (tver <= 1) continue; // not a real task
		delta[uid] = JSON.stringify(t);
		delta['v'+uid] = tver;
	}
	state.submitDelta(delta);
}


function completeTasks(taskArr) { // sets completed
	updateTasks(taskArr, function(t) {
		t.completer = wave.getViewer().getId();
		t.completedDate = new Date();
	});
}

function uncompleteTasks(taskArr) { // sets not completed
	updateTasks(taskArr, function(t) {
		t.completer = '';
		t.completedDate = null;
	});
}

function deleteTasks(taskArr) { // sets as deleted
	updateTasks(taskArr, function(t) {
		t.progress = -1;
	});
}

function postponeTasks(taskArr) { // adds 1 day to dueDate
	updateTasks(taskArr, function(t) {
		if(t.dueDate) t.dueDate.addDays(1);
	});
}

function prioritizeTasks(taskArr, prio) { // sets priority
	updateTasks(taskArr, function(t) {
		if (prio == '--' && t.priority > 1) t.priority--;
		else if (prio == '++' && t.priority < 4) t.priority++;
		else if (validPriority(prio)) t.priority = prio;
	});
}

function duplicateTasks(taskArr) { // duplicates as new
	for (var i in taskArr) {
		var t = cloneTask(taskArr[i]);
		t.completedDate = null;
		t.completer = '';
		addTask(t);
	}
}

function delegateTasks(taskArr, owner) { // sets owner
	updateTasks(taskArr, function(t) {
		t.owner = owner;
	});
}
